import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import map.NodeDataBase;
import map.NodeSlot;

/**
 * @author balage
 *
 */
public class MapCanvas extends Canvas {

	private static final long serialVersionUID = -8003773640340062119L;

	double latc = 47.5;
	double lonc = 17.5;
	
	double scale = 0.0001;
	
	NodeDataBase ndb;
	
	File ndbfile; 
	
	public MapCanvas(File dir) {
//		if (dir.isDirectory()){
//			String[] fs = dir.list();
//			System.out.println("Files: "+fs.length);
//			for(int i=0;i<fs.length;i++)
//				System.out.println(fs[i]);
//		}else{
//			System.err.println("Not a directory!");
//		}
		try {
			ndbfile = new File(dir,"map.ndb");
			ndb = new NodeDataBase(ndbfile);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void drag(int x, int y){
		latc += scale*x;
		lonc += scale*y;
		//System.out.println(latc+" "+lonc);
		this.repaint();
	}
	
	public void update(Graphics g) {
		paint(g);
	}
	
	public Dimension getPreferredSize() {
		return getSize();
	}
	
	private final HashMap nodepoz = new HashMap();
	private final List ways = new ArrayList();
	
	public void paint(Graphics g) {
		g.setColor(new Color(255, 255, 255));
		g.fillRect(0, 0, getWidth(), getHeight());
		
		Color border = new Color(200,50,50);
		Color road = new Color(0,0,0);
		Color unknown = new Color(150,150,150);
		
		Dimension d = getSize();
		d.width /= 2;
		d.height /= 2;
		List nodes;
		try {
			if (ndbfile.exists()){
				nodes = ndb.getNodes(2,latc-d.width*scale, lonc-d.height*scale, latc+d.width*scale, lonc+d.height*scale);
				nodepoz.clear();
				ways.clear();
				NodeSlot lastnode = null;
				for(int i = 0;i<nodes.size();i++){
					NodeSlot ns = (NodeSlot)nodes.get(i);
					if (ns.type == NodeSlot.TYPE_NODE){
						lastnode = ns;
						double lat = Double.longBitsToDouble(ns.l1);
						double lon = Double.longBitsToDouble(ns.l2);
						int x = (int)Math.round((lat-(latc-d.width*scale))/scale);
						int y = (int)Math.round((lon-(lonc-d.height*scale))/scale);
						nodepoz.put(new Long(ns.poz), new Point(x, y));
					}else if (lastnode != null){
						ns.poz = lastnode.poz;
						ways.add(ns);
					}
					//g.fillRect(x-2, y-2, 4, 4);
					//System.out.println(lat+","+lon);
				}
				
				for(int i=0;i<ways.size();i++){
					NodeSlot ns = (NodeSlot)ways.get(i);
					Point p1 = (Point)nodepoz.get(new Long(ns.poz));
					Point p2 = (Point)nodepoz.get(new Long(ns.l2));
					if (p1 != null && p2 != null){
						switch((int)ns.l1/NodeSlot.WAYTYPE_SEPARATOR){
						case NodeSlot.WTYPE_BOUNDARY: g.setColor(border); break;
						case NodeSlot.WTYPE_HIGHWAY: g.setColor(road); break;
						default: g.setColor(unknown);
						}
						g.drawLine(p1.x, p1.y, p2.x, p2.y);
					}
				}
			g.drawString("zoom: "+scale, 0, 80);
			g.drawString("nodes: "+nodes.size(), 0, 100);
			}else{
				g.drawString("Can't load file", 0, 80);
				g.drawString(ndbfile.getAbsolutePath(), 0, 100);
			}
		} catch (Exception e) {
			e.printStackTrace();
			g.drawString(new File(".").getAbsolutePath(), 0, 80);
			String es = e.getMessage();
			g.drawString(es==null?"null":es, 0, 100);
		}
		
		g.setColor(new Color(150,150,150));
		
		g.drawRoundRect(160, 10, 30, 30, 5, 5);
		g.fillRect(165, 22, 20, 6);
		g.fillRect(172, 15, 6, 20);
		
		g.drawRoundRect(160, 50, 30, 30, 5, 5);
		g.fillRect(165, 62, 20, 6);
		
		g.setColor(new Color(0,0,0));
		g.drawString(latc+"", 0, 20);
		g.drawString(lonc+"", 0, 32);
		
		long max = Runtime.getRuntime().totalMemory()/(1024);
		long free = Runtime.getRuntime().freeMemory()/(1024);
		int s = d.width*2 - 30;
		
		g.setColor(new Color(200,200,200));
		g.drawRect(15, d.height*2-25, s, 20);
		g.fillRect(15, d.height*2-25, (int)(s*(max-free)/max), 20);
		
		g.setColor(new Color(0,0,0));
		g.drawString((max-free)+"K / "+max+"K", 17, d.height*2-10);
	}
	
	public void click(int x, int y){
		if (x >= 160 && x <=190){
			if (y>=10 && y<=40){
				scale *= 0.8;
				repaint();
			}else
			if (y>=50 && y<=80){
				scale *= 1.25;
				repaint();
			}
		}
	}
	
}
